package com.bauer.java.pdf.text;

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import java.util.HashMap;
import org.apache.commons.beanutils.BeanUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;

/**
 * @Author ：rui.wei
 * @Date ：Created in 9:31 2019/3/7
 * @Description：
 */
public class PDFUtils {

    public static void main(String[] args) throws FileNotFoundException {
        Map<String, String> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("id", "测试");
        objectObjectHashMap.put("year", "测试");
        objectObjectHashMap.put("month", "测试");
        objectObjectHashMap.put("date", "测试");
        objectObjectHashMap.put("name", "测试");
        objectObjectHashMap.put("authorizer", "测试");

        fillParam("D:\\mine\\java\\pdf\\src\\main\\resources\\waimaoPersonInfoAuth.pdf",
            "D:\\mine\\java\\pdf\\src\\main\\resources\\waimaoPersonInfoAuth1.pdf", objectObjectHashMap);
    }


    public static void fillParam(String templeFile, String targetFile, Object object)
        throws FileNotFoundException {
        File file = new File(targetFile);

        fillParam(templeFile, new FileOutputStream(file), object);
    }


    public static void fillParam(String templeFile, OutputStream outputStream, Object object)
        throws FileNotFoundException {
        File file = new File(templeFile);

        if (!file.exists()) {
            throw new FileNotFoundException("file does not exist fileName:" + templeFile);
        }

        fillParam(new FileInputStream(file), outputStream, object);
    }

    public static void fillParam(InputStream inputStream, OutputStream outputStream,
        Object object) {

        //将bean转换过成Map
        Map<String, Object> filedsMap = converObjectToMap(object);
        if (filedsMap == null) {
            return;
        }

        PdfReader pdfReader;
        PdfStamper pdfStamper = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        Document doc = new Document();
        try {
            pdfReader = new PdfReader(inputStream);
            pdfStamper = new PdfStamper(pdfReader, bos);
            //设置为不可编辑
            pdfStamper.setFormFlattening(true);

            //设置字体否则中文会不显示
            BaseFont bfChinese = BaseFont
                .createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            //设置域值
            AcroFields acroFields = pdfStamper.getAcroFields();
            acroFields.addSubstitutionFont(bfChinese);
            if (acroFields != null) {
                Iterator<String> iterable = acroFields.getFields().keySet().iterator();

                while (iterable.hasNext()) {
                    String filedName = iterable.next();
                    if (filedsMap.get(filedName) != null) {
                        acroFields.setField(filedName, filedsMap.get(filedName).toString());
                    }
                }
            }
            //需要先关闭再回写
            pdfStamper.close();

            //回写
            PdfCopy copy = new PdfCopy(doc, outputStream);
            doc.open();
            doc.newPage();
            copy.addDocument(new PdfReader(bos.toByteArray()));

        } catch (Exception io) {
            io.printStackTrace();
        } finally {
            try {
                if (doc != null) {
                    doc.close();
                }
            } catch (Exception e) {

            }
        }
    }


    private static Map<String, Object> converObjectToMap(Object obj) {
        if (obj == null) {
            return null;
        }

        if (obj instanceof Map) {
            return (Map<String, Object>) obj;
        }

        try {
            return BeanUtils.describe(obj);
        } catch (Exception e) {
            return null;
        }

    }

}
